package com.heima.user.service.impl;

import com.heima.common.constants.user.ApUserConstants;
import com.heima.common.constants.user.UserRelationConstants;
import com.heima.common.exception.CustException;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.dtos.UserRelationDTO;
import com.heima.model.user.pojos.ApUser;
import com.heima.user.service.ApUserRelationService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @Author XHui
 * @Since 2024/2/18 18:12
 * @Version 1.0
 */
@Service
public class ApUserRelationServiceImpl implements ApUserRelationService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 关注作者
     *
     * @param dto DTO
     * @return 通用的结果返回类
     */
    @Override
    public ResponseResult follow(UserRelationDTO dto) {
        // 1. 检查参数(是否登录 operation: 0 1 自己不能关注自己 是否已经关注)
        ApUser loggedUser = AppThreadLocalUtils.getUser();
        if (loggedUser == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN, "请先登录");
        }
        int operationValue = dto.getOperation().intValue();
        if (operationValue != 0 && operationValue != 1) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,
                    "关注类型错误 应为0(关注) 或 1(未关注)");
        }
        // 2. operation = 0 关注， 关注集合 粉丝集合 添加数据
        // 自己不能关注自己, 给出提示redis代码
        String authorUserIdString = dto.getAuthorApUserId().toString();
        String userIdString = loggedUser.getId().toString();
        String followKey = UserRelationConstants.FOLLOW_LIST + loggedUser.getId();
        String fansKey = UserRelationConstants.FANS_LIST + authorUserIdString;

        ZSetOperations<String, String> zSet = stringRedisTemplate.opsForZSet();
        if (ApUserConstants.USER_OPERATION_FOLLOW == operationValue) {

            if (Objects.equals(loggedUser.getId(), dto.getAuthorApUserId())) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "自己不能关注自己");
            }

            // zscore 集合的key 元素
            // 返回值不为null 该元素存在该集合中
            //  返回值为null 该元素不存在该集合中
            //  查询当前作者是否被关注了
            Double score = zSet.score(
                    followKey,
                    authorUserIdString
                    );

            if (score != null) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "请勿重复关注");
            } else {
                // 用户1 关注了 用户2
                // 1的角度：1关注了2
                // 2的角度：1是2的粉丝
                zSet.add(followKey,
                        authorUserIdString,
                        System.currentTimeMillis());

                zSet.add(fansKey,
                        userIdString,
                        System.currentTimeMillis());
            }

        }else {
            // 3. operation = 1 取关， 关注集合 粉丝集合 删除数据
            zSet.remove(followKey, authorUserIdString);
            zSet.remove(fansKey, authorUserIdString);
        }
        return ResponseResult.okResult();
    }
}
